/* You may freely copy, distribute, and reuse the code in this example.
 * NeXT disclaims any warranty of any kind, expressed or  implied, as to its
 * fitness for any particular use.
 * 
 */

#import <appkit/Application.h>
#import <appkit/NXImage.h>
#import <appkit/nextstd.h>
#import <objc/NXStringTable.h>
//#import <appkit/defaults.h>
#import <libc.h>
#import "Localization.h"

#define NATIVE_LANGUAGE "English"
static char *launchDir = NULL;	/* if this is NULL, it will be calculated */

/*
 * launchDirOK will return a NULL launchDir if you launch from a Terminal Shell. 
 */
static BOOL launchDirOk()
{
    const char *slash;

    if (launchDir) return YES;

    slash = strrchr(NXArgv[0], '/');
    if (slash && slash-NXArgv[0]) {
	launchDir = malloc((slash-NXArgv[0]+1)*sizeof(char));
	strncpy(launchDir, NXArgv[0], slash-NXArgv[0]);
	launchDir[slash-NXArgv[0]] = '\0';
	return YES;
    }

    return NO;
}

void InitLocalDateAndTime()
{
    time_t t;
    char buffer[16];
    t = time(NULL);
    strftime(buffer, 15, "%H:%M", localtime(&t));
}

		
void LocalDateAndTime(char *buffer,int  maxBufferSize, const time_t *time) 
{
    const char *format;
    
    format = NXGetDefaultValue([NXApp appName], "NXDateAndTime");
    if (format == NULL)
        format = "%a %b %d %H:%M:%S %Z %Y";
    strftime(buffer,maxBufferSize,format,localtime(time));
}

void LocalDate(char *buffer,int  maxBufferSize, const time_t *time)
{
    const char *format;
    
    format = NXGetDefaultValue([NXApp appName], "NXDate");
    if (format == NULL)
        format = "%a %b %d %Y";
    strftime(buffer,maxBufferSize,format,localtime(time));
}

void LocalTime(char *buffer,int maxBufferSize, const time_t *time)
{
    const char *format;
    
    format = NXGetDefaultValue([NXApp appName], "NXTime");
    if (format == NULL)
        format = "%H:%M:%S %Z";
    strftime(buffer,maxBufferSize,format,localtime(time));
}


/* If the user has not set a language preference, load the nib
 * section stored in the Mach-O by default. Otherwise,
 * the nib file loaded would follow the language set in the Preferences
 * Application.
 */
id LoadLocalNib(const char *nibFile, id owner, BOOL withName, NXZone *zone)
{
    BOOL found = NO;
    id retval = nil;
    const char *const *languages;
    char path[MAXPATHLEN+1];

    languages = [NXApp systemLanguages];

    if (languages && launchDirOk()) {
	while (!found && *languages) {
	    //if (!strcmp(*languages, NATIVE_LANGUAGE))  	break;
	    sprintf(path, "%s/%s.lproj/%s", launchDir, *languages, nibFile);
	    if (!access(path, R_OK)) {
		if ( zone == NULL){ 
		    retval = [NXApp loadNibFile:path owner:owner 
				withNames:NO];
		    found = YES;
		}
		else {
		    retval = [NXApp loadNibFile:path owner:owner 
				withNames:withName fromZone:zone];
		    found = YES;
		}
	    }
	languages++;
	}
    }

    if ( zone == NULL) 
       return found ? retval : [NXApp loadNibSection:nibFile owner:owner
				withNames:NO];
    else
       return found ? retval : [NXApp loadNibSection:nibFile owner:owner
				withNames:withName fromZone:zone];
}

NXStream *LocalMapFile(const char *file, int flag)
{
    BOOL found = NO;
    const char *const *languages;
    char path[MAXPATHLEN+1];
    NXStream	*stream=NULL;

    languages = [NXApp systemLanguages];

    if (languages && launchDirOk()) {
	while (!found && *languages) {
	    sprintf(path, "%s/%s.lproj/%s", launchDir, *languages, file);
	    if (!access(path, R_OK)) {
		stream = NXMapFile(path, flag);
		found = YES;
	    }
	languages++;
	}
    }
    if (!found) {
	sprintf(path, "%s/%s", launchDir, file);
	stream = NXMapFile(path, flag);
    }
    return (NXStream *)stream;
}



id LocalImage(const char *file)
{
    id retval = nil;
    const char *const *languages;
    char path[MAXPATHLEN+1];

    languages = [NXApp systemLanguages];
    if (languages) {
	while (!retval && *languages) {
	    if (!strcmp(*languages, NATIVE_LANGUAGE)) break;
	    sprintf(path, "%s/%s.lproj/%s", launchDir, *languages, file);
	    retval = [NXImage newFromFile:file];
	    languages++;
	}
    } else {
	retval = [NXImage newFromSection:file];
    }

    return retval;
}

/* If the user has not selected a language preference,
 * return the key by default. 
 * NOTE: The key is in the same language as the NATIVE_LANGUAGE.
 */
 
const char *doLocalString(const char *tableName, const char *key, const char *value)
{
    id table = nil;
    const char *tableValue;
    const char *const *languages;
    BOOL isMyAppsLanguage = NO;
    char buffer[MAXPATHLEN+1];
    static int debugLanguages = -1;
    static id stringTableTable = nil;

    if (!(languages = [NXApp systemLanguages])) return value ? value : key;

    if (!tableName) tableName = [NXApp appName];
    if (tableName[0] == '"' && tableName[strlen(tableName)-1] == '"') {
	strcpy(buffer, tableName+1);
	buffer[strlen(buffer)-1] = '\0';
	tableName = NXUniqueString(buffer);
    }

    if (debugLanguages < 0) debugLanguages = NXGetDefaultValue([NXApp appName], "NXDebugLanguages") ? 1 : 0;

    if (!(table = [stringTableTable valueForKey:tableName])) {
	while (!table && *languages) {
	    if (!strcmp(*languages, NATIVE_LANGUAGE)) {
		isMyAppsLanguage = YES;
/*
		sprintf(buffer, "%s/%s.lproj/%s.strings", launchDir, *languages, tableName);
                table =  [[NXStringTable alloc] init] ;
		[table readFromFile:buffer];
		
*/
		break;
	    } 
	    sprintf(buffer, "%s/%s.lproj/%s.strings", launchDir, *languages, tableName);
	    table =  [[NXStringTable alloc] init] ;
	    [table readFromFile:buffer];
		languages++;
	}
	if (!table) {
	    if (debugLanguages && !isMyAppsLanguage) NXLogError("Cannot parse '%s' strings.", tableName);
	    table = [NXStringTable new];
	}
	if (!stringTableTable) stringTableTable = [HashTable newKeyDesc:"*"];
	[stringTableTable insertKey:tableName value:table];
    }

    tableValue = [table valueForStringKey:key];

    if (!tableValue) {
	if (debugLanguages && !isMyAppsLanguage)
	    NXLogError("Cannot find value for string '%s' in table '%s'.", key, tableName);
	tableValue = value ? value : key;
	[table insertKey:key value:(void *)value];
    }
/*
    NXHashState state;
    const char *dkey;const char *dvalue;

	state=[table initState];
		while([table nextState:(NXHashState *)&state key:(const void **)&dkey value:(void **)&dvalue] == YES)
			printf("key = %s, value = %s\n",dkey,dvalue);
*/

    return tableValue;
}
